package com.blog.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blog.constant.MsgConstant;
import com.blog.mapper.NoteMapper;
import com.blog.pojo.dto.NoteDTO;
import com.blog.pojo.entity.Note;
import com.blog.service.NoteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class NoteServiceImpl extends ServiceImpl<NoteMapper, Note> implements NoteService {

    /**
     * 分页查询笔记
     * @param currentPage
     * @param pageSize
     * @param content
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public IPage<Note> getNoteListPage(Integer currentPage, Integer pageSize, String content) {
        // 1. 创建Page对象，设置分页条件
        Page page = new Page<>(currentPage, pageSize);

        // 2. 创建wrapper对象, 设置查询的条件
        LambdaQueryWrapper<Note> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(content)) {
            wrapper.like(Note::getContent, content);
        }

        // 3. 设置查询到的数据按照创建时间从最新排序
        wrapper.orderByDesc(Note::getCreateTime);

        // 4. 进行查询并返回数据
        try {
            return this.page(page, wrapper);
        } catch (Exception e) {
            log.info("分页查询笔记失败:{}", e);
            throw new RuntimeException(MsgConstant.NOTE_SELECT_ERROR);
        }

    }

    /**
     * 添加笔记
     * @param noteDTO
     */
    @Override
    public void addNote(NoteDTO noteDTO) {
        // 1. 将DTO对象转换成Note实体
        Note note = BeanUtil.copyProperties(noteDTO, Note.class);

        // 2. 设置时间
        note.insertTime();

        //进行添加操作
        try {
            this.save(note);
        } catch (Exception e) {
            log.error("添加笔记失败：", e);
            throw new RuntimeException(MsgConstant.NOTE_ADD_ERROR);
        }
    }

    /**
     * 修改笔记
     * @param noteDTO
     */
    @Override
    public void updateNote(NoteDTO noteDTO) {
        // 1. 先检查要修改的笔记是否存在于数据库中
        if (this.getById(noteDTO.getId()) == null) {
            throw new RuntimeException(MsgConstant.NOTE_NO_EXISTS);
        }

        // 2. 将DTO对象转换成Note实体并设置修改时间
        Note note = BeanUtil.copyProperties(noteDTO, Note.class);
        note.updateTime();

        // 3. 进行修改操作
        try {
            this.updateById(note);
        } catch (Exception e) {
            log.info("修改笔记失败：{}", e);
            throw new RuntimeException(MsgConstant.NOTE_UPDATE_ERRPR);
        }

    }

    /**
     * 删除单个笔记
     * @param id
     */
    @Override
    public void deleteNote(Long id) {
        // 1. 先检查要删除的笔记是否存在于数据库中
        if (this.getById(id) == null) {
            throw new RuntimeException(MsgConstant.NOTE_NO_EXISTS);
        }

        // 2. 进行删除操作
        try {
            this.removeById(id);
        } catch (Exception e) {
            log.info("删除单个笔记失败: {}", e);
            throw new RuntimeException(MsgConstant.NOTE_DELETE_ERROR);
        }

    }

    /**
     * 批量删除笔记
     * @param ids
     */
    @Override
    public void deleteNotes(List<Long> ids) {
        // 1. 先检查要删除的笔记是否都存在于数据库中
        LambdaQueryWrapper<Note> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Note::getId, ids);
        if (this.count(wrapper) != ids.size()) {
            throw new RuntimeException(MsgConstant.NOTE_NO_EXISTS);
        }

        // 2. 进行批量删除操作
        try {
            this.removeBatchByIds(ids);
        } catch (Exception e) {
            log.info("批量删除笔记失败：{}", e);
            throw new RuntimeException(MsgConstant.NOTE_DELETE_ERROR);
        }
    }
}
